#pragma once
#include "vision_global.h"

#include <QImage>
#include <vector>
#include <opencv2/opencv.hpp>
#include "HalconCpp.h"
//#include <math.h>
//#include "AIDataDefine.h"

using namespace HalconCpp;

#include <QCoreApplication>
#include <QThread>

template<typename F>
void postToThread(F&& fun, QThread* thread = qApp->thread()) {
	auto* obj = QAbstractEventDispatcher::instance(thread);
	Q_ASSERT(obj);
	QMetaObject::invokeMethod(obj, std::forward<F>(fun));
}

// 定义常量PI值
const double pi = atan2(0, -1);

// 目标的中心；角度；长、短轴；
// 旋转矩形
typedef struct tagObjPos
{
	double x;
	double y;
	double angle;
	double len1;
	double len2;
}ObjPos, * PObjPos, RotRect;

namespace VisionApi
{
	using cvContour = std::vector<cv::Point>;	// 轮廓
	using cvContourSet = std::vector<cvContour>;	// 轮廓集
	using polygonPoints = std::vector<cv::Point2f>;

	VISION_EXPORT bool isFileExist(const char* filePath);
	VISION_EXPORT bool isDirExist(const char* dir);

	// 圆拟合
	// 最小二乘法
	VISION_EXPORT bool fitCircle_LeastSquares(const std::vector<cv::Point2d>& points, cv::Point2d* center, double* radius, double *rmse);
	// RANSAC拟合：随机抽样一致性算法
	VISION_EXPORT bool fitCircle_RANSAC(const std::vector<cv::Point2d>& points, 
		float* center_x, float* center_y, double* radius, int maxIterCnt=100, double maxErrorThreshold=5.0);

	VISION_EXPORT ObjPos getObjPos(HImage src, HRegion roi, double thresh=128);
	VISION_EXPORT std::vector<ObjPos> inspAllObjPos(HImage src);

	/// <summary>
	/// 图像类型转换：Halcon opencv qt三种常见数据结构的转换
	/// HImage cv::Mat QImage
	/// </summary>
	/// <param name="src"></param>
	/// <returns></returns>
	VISION_EXPORT HImage HImageFromMat(cv::Mat& src);
	VISION_EXPORT bool QImage2HImage(QImage& from, HalconCpp::HImage& to);
	VISION_EXPORT bool HImage2QImage(HalconCpp::HImage& from, QImage& to);

	VISION_EXPORT QImage mat2QImage(cv::Mat& mat);
	VISION_EXPORT cv::Mat qImage2Mat(QImage& image);

	// 弧度与角度计算：halcon常用
	VISION_EXPORT double rad2Deg(double rad);
	VISION_EXPORT double deg2Rad(double deg);

	// 旋转：绕参考点或者原点旋转
	// 绕参考点旋转
	// 1.基础数据结构
	// 绕原点旋转
	VISION_EXPORT void rotatePoint(double x, double y, double rotAngle, double* outX, double* outY);
	// 绕参考点旋转
	VISION_EXPORT void rotatePoint(double x, double y, double refX, double refY, double rotAngle, double* outX, double* outY);
	// 2.opencv点数据结构
	// 绕原点旋转
	VISION_EXPORT void rotatePoint(const cv::Point2d& p, double rotAngle, cv::Point2d* outPoint);
	VISION_EXPORT cv::Point2d rotatePoint(const cv::Point2d& p, double rotAngle);

	VISION_EXPORT void rotatePoint(const cv::Point2d& p, double rotAngle, const cv::Point2d& refPoint, cv::Point2d* outPoint);
	VISION_EXPORT cv::Point2d rotatePoint(const cv::Point2d& p, double rotAngle, const cv::Point2d& refPoint);

	VISION_EXPORT cv::Point2d arrowEndPoint(const cv::Point2d& startPt, double len, double angle);

	// 简单绘制函数
	// 绘制“十”字点
	VISION_EXPORT void drawCross(cv::Mat& src, cv::Point pt, cv::Scalar color = cv::Scalar(0, 0, 255), cv::Size sz = cv::Size(3, 3));
	// 文本输出绘制
	VISION_EXPORT void textOut(cv::Mat& src, cv::Point pt, cv::Scalar color = cv::Scalar(0, 0, 255));

	VISION_EXPORT void genPolygonFromRect2(cv::Point2d* points, const RotRect& rect2);
	// 旋转矩形绘制
	VISION_EXPORT void drawRotRect(cv::Mat& src, RotRect r, cv::Scalar color = cv::Scalar(0, 255, 0));

	// 轮廓绘制（halcon）
	VISION_EXPORT void drawHalconXld(cv::Mat& src, HXLDCont& xld, cv::Scalar color = cv::Scalar(0, 0, 255));
	// 轮廓绘制（opencv）
	VISION_EXPORT void drawOpencvContour(cv::Mat& src, std::vector<polygonPoints>& allContours, cv::Scalar color = cv::Scalar(0, 0, 255));

	//VISION_EXPORT void drawInferResults(cv::Mat& src, DetectResultList& inferResults);
};

